package cn.lili.controller.wallet;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.lili.common.enums.DictCodeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.utils.SysDictUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.RechargeFow;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.member.service.PartnerService;
import cn.lili.modules.member.service.RechargeFowService;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.store.service.StoreDetailService;
import cn.lili.modules.system.aspect.annotation.SystemLogPoint;
import cn.lili.modules.wallet.entity.dos.MemberWallet;
import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply;
import cn.lili.modules.wallet.entity.dos.MemberWithdrawItem;
import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage;
import cn.lili.modules.wallet.entity.enums.WalletOwnerEnum;
import cn.lili.modules.wallet.entity.enums.WithdrawStatusEnum;
import cn.lili.modules.wallet.entity.vo.MemberSalesWithdrawVO;
import cn.lili.modules.wallet.entity.vo.MemberWithdrawApplyQueryVO;
import cn.lili.modules.wallet.entity.vo.MemberWithdrawApplyVO;
import cn.lili.modules.wallet.service.MemberWithdrawItemService;
import cn.lili.modules.wallet.service.MemberWithdrawApplyService;
import cn.lili.modules.wallet.serviceimpl.MemberWalletServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

/**
 * 买家端,余额提现记录接口
 *
 * @author pikachu
 * @since 2020/11/16 10:07 下午
 */
@RestController
@Api(tags = "买家端,余额提现记录接口")
@RequestMapping("/buyer/member/withdrawApply")
@Transactional(rollbackFor = Exception.class)
public class MemberWithdrawApplyBuyerController {
	@Autowired
	private MemberWithdrawApplyService memberWithdrawApplyService;

	@Autowired
	private StoreDetailService storeDetailService;

	@Autowired
	private MemberWithdrawItemService memberWalletItemService;

	@Autowired
	private MemberWalletServiceImpl walletDetailService;

	@Autowired
	private PartnerService partnerService;

	/**
	 * 订单 MemberWalletItemDTO
	 */
	@Autowired
	private OrderService orderService;

	@Autowired
	private RechargeFowService rechargeFowService;

	@Autowired
	private MemberService memberService;

	@ApiOperation(value = "分页获取提现记录")
	@GetMapping
	public ResultMessage<IPage<MemberWithdrawApplyVO>> getByPage(PageVO page,
			MemberWithdrawApplyQueryVO memberWithdrawApplyQueryVO) {
		memberWithdrawApplyQueryVO.setMemberId(UserContext.getCurrentUser().getId());
		// 构建查询 返回数据
		IPage<MemberWithdrawApplyVO> memberWithdrawApplyPage = memberWithdrawApplyService.getMemberWithdrawPage(page,
				memberWithdrawApplyQueryVO);
		return ResultUtil.data(memberWithdrawApplyPage);
	}

	@ApiOperation(value = "提现申请撤销")
	@PostMapping
	@ApiImplicitParams({@ApiImplicitParam(name = "applyId", value = "审核记录id", required = true, paramType = "query"),})
	public Boolean audit(String applyId) {
		return memberWithdrawApplyService.audit(applyId, WithdrawStatusEnum.CANCEL.name(), null);
	}

	@ApiOperation(value = "获取当前人店铺提现金额")
	@RequestMapping("/getdeposit")
	public ResultMessage<IPage<MemberSalesWithdrawVO>> getdeposit(PageVO page,
			MemberSalesWithdrawVO memberWithdrawApplyQueryVO) {
		IPage<MemberSalesWithdrawVO> getdeposit = memberWithdrawApplyService.getdeposit(page,
				memberWithdrawApplyQueryVO);
		return ResultUtil.data(getdeposit);
	}

	@ApiModelProperty(value = "退回金额")
	@RequestMapping("/getsums")
	public ResultMessage<List<MemberSalesWithdrawVO>> getsums(String idArr) {
		String id = UserContext.getCurrentUser().getId();
		List<MemberWithdrawApply> applyList = memberWithdrawApplyService.getList(idArr);
		int i = 0;
		for (MemberWithdrawApply apply : applyList) {
			List<MemberWithdrawItem> itemDtoBySnList = memberWalletItemService.findItemDtoBySn(apply.getSn());
			String Apply = apply.getApplyStatus();
			if(CollectionUtils.isNotEmpty(itemDtoBySnList)) {
				for (MemberWithdrawItem item : itemDtoBySnList) {
					memberWalletItemService.batchUpdatemoney("0", BigDecimal.valueOf(item.getApplyMoney()), item.getOrderItemId(),
						item.getRealMoney().toString());// 修改提现的订单
					i++;
					if (i == itemDtoBySnList.size()) {
						String owners = apply.getOwner();
						String subowner = owners;
						if (owners.indexOf("STORE") != -1) {
							subowner = owners.substring(6);
						} else if (owners.indexOf("BUYER") != -1) {
							subowner = owners.substring(6);
						}
						MemberWallet to = walletDetailService.getMemberWalletInfo(id, subowner);
						MemberWallet admin = walletDetailService.getMemberWalletInfo("admin", subowner, "平台");// 平台消费钱包
						walletDetailService
							.withdrawApplyRefund(apply.getSn(), admin, to, apply.getApplyPrice(), "余额提现退回，拒绝原因：主动撤销");
						Integer integer = memberWithdrawApplyService.UpdateApplyStaytus("CANCEL", idArr);
						return ResultUtil.success(ResultCode.ORDER_STATUS_SUCCESS);
					}
				}
			}else{
				String owners = apply.getOwner();
				String subowner = owners;
				if (owners.indexOf("STORE") != -1) {
					subowner = owners.substring(6);
				} else if (owners.indexOf("BUYER") != -1) {
					subowner = owners.substring(6);
				}
				MemberWallet to = walletDetailService.getMemberWalletInfo(id, subowner);
				MemberWallet admin = walletDetailService.getMemberWalletInfo("admin", subowner, "平台");// 平台消费钱包
				walletDetailService
					.withdrawApplyRefund(apply.getSn(), admin, to, apply.getApplyPrice(), "余额提现退回，拒绝原因：主动撤销");
				Integer integer = memberWithdrawApplyService.UpdateApplyStaytus("CANCEL", idArr);
				return ResultUtil.success(ResultCode.ORDER_STATUS_SUCCESS);
			}
		}
		return ResultUtil.error(ResultCode.PARAMS_ERROR);
	}

	// 提现列表查询
	@RequestMapping("/queryList")
	public ResultMessage<IPage<MemberWithdrawApply>> queryList(PageVO page, MemberWithdrawApply memberWithdrawApply,
			String owner) {

		AuthUser currentUser = UserContext.getCurrentUser();
		// if (owner=="SALE" || owner.equals("SALE")){
		// memberWithdrawApply.setOwner("STORE_SALE");
		// }
		QueryWrapper<MemberWithdrawApply> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("delete_flag", "0");
		queryWrapper.eq(CharSequenceUtil.isNotEmpty(currentUser.getId()), "member_id", currentUser.getId());
		queryWrapper.like(StringUtils.isNotEmpty(memberWithdrawApply.getOwner()), "owner",
				memberWithdrawApply.getOwner());
		queryWrapper.apply(" DATE_FORMAT( create_time, '%Y%m' ) = DATE_FORMAT( CURDATE( ) , '%Y%m' )");
		queryWrapper.orderByDesc("create_time");
		IPage<MemberWithdrawApply> memberWithdrawApplyIPage = memberWithdrawApplyService.queryWithdrawApplyList(page,
				queryWrapper);
		return ResultUtil.data(memberWithdrawApplyIPage);
	}

	// 根据焕呗额计算对应现金和折扣率
	@RequestMapping("/countPrice")
	@SystemLogPoint(description = "钱包提现", customerLog = "钱包提现请求", type = "2")
	public ResultMessage<Map<String, Object>> countPrice(String owner, Double price) {
		if (null != price && price.compareTo(0D) > 0) {
			Double p = price;
			Map<String, Object> map = new HashMap<>();
			Double fee = 0D;// 折扣率
			Double money = 0D;// 现金
			if (owner.equals(WalletOwnerEnum.PROMOTE_HY.name())) {
				// 推广钱包-会员费
				QueryWrapper<RechargeFow> queryWrapper = new QueryWrapper<>();
				queryWrapper.eq("member_id", UserContext.getCurrentUser().getId());
				queryWrapper.eq("realization", "0");
				queryWrapper.orderByAsc("add_time");
				List<RechargeFow> rechargeFowList = rechargeFowService.list(queryWrapper);
				Double alreadyMoney = 0D;// 已扣除现金
				Double alreadyPrice = 0D;// 已扣除焕呗
				if (CollectionUtils.isNotEmpty(rechargeFowList)) {
					for (RechargeFow rechargeFow : rechargeFowList) {
						// 循环出每一次的充值记录
						if (price.compareTo(rechargeFow.getCanHuanBei()) >= 0) {
							// 应扣除焕呗额大于等于可扣除焕呗额，把整条记录都扣完
							alreadyMoney = CurrencyUtil.add(alreadyMoney, rechargeFow.getCanMoney());// 增加已扣除现金
							alreadyPrice = CurrencyUtil.add(alreadyPrice, rechargeFow.getCanHuanBei());// 增加已扣除焕呗
							price = CurrencyUtil.sub(price, rechargeFow.getCanHuanBei());// 应扣除焕呗额减少
						} else {
							// 应扣除焕呗额小于可扣除焕呗额，只扣除一部分
							Double canMoney = CurrencyUtil.mul(price, rechargeFow.getFee());// 扣除现金 = 应扣除焕呗额 * 费率

							alreadyMoney = CurrencyUtil.add(alreadyMoney, canMoney);// 增加已扣除现金
							alreadyPrice = CurrencyUtil.add(alreadyPrice, price);// 增加已扣除焕呗
							price = 0D;
							break;
						}
					}

					money = alreadyMoney;
					// fee = CurrencyUtil.div(alreadyMoney, alreadyPrice);
					fee = CurrencyUtil.div(money, p);
				} else {
					throw new ServiceException(ResultCode.CAN_NOT_BALANCE);
				}
			} else if (StrUtil.equalsAny(owner, WalletOwnerEnum.PROMOTE_FW.name(), WalletOwnerEnum.PROMOTE.name())) {
				// 推广钱包-服务费，推广钱包
				// 获取当前登录人的合伙人类型
				String member = memberService.findByPartner(UserContext.getCurrentUser().getId());
				fee = Double.parseDouble(
						SysDictUtils.getValueString(DictCodeEnum.PROMOTE_WITHDRAWAL_RATE.dictCode(), member));
				money = CurrencyUtil.mul(fee, price);
			} else if (owner.equals(WalletOwnerEnum.SALE.name())) {
				// 销售钱包
				List<MemberSalesWithdrawVO> feeSum = memberWithdrawApplyService.getFeesum(null);
				Double alreadyMoney = 0D;// 已扣除现金
				Double alreadyPrice = 0D;// 已扣除焕呗
				if (CollectionUtils.isNotEmpty(feeSum)) {
					for (MemberSalesWithdrawVO withdraw : feeSum) {
						// 循环出每一次的充值记录
						if (price.compareTo(withdraw.getSurplusPrice()) >= 0) {
							// 应扣除焕呗额大于等于可扣除焕呗额，把整条记录都扣完
							alreadyMoney = CurrencyUtil.add(alreadyMoney, withdraw.getSurplus());// 增加已扣除现金
							alreadyPrice = CurrencyUtil.add(alreadyPrice, withdraw.getSurplusPrice());// 增加已扣除焕呗
							price = CurrencyUtil.sub(price, withdraw.getSurplusPrice());// 应扣除焕呗额减少
						} else {
							// 应扣除焕呗额小于可扣除焕呗额，只扣除一部分
							Double canMoney = CurrencyUtil.mul(price, withdraw.getFee());// 扣除现金 = 应扣除焕呗额 * 费率

							alreadyMoney = CurrencyUtil.add(alreadyMoney, canMoney);// 增加已扣除现金
							alreadyPrice = CurrencyUtil.add(alreadyPrice, price);// 增加已扣除焕呗
							price = 0D;
							break;
						}
					}

					money = alreadyMoney;
					// fee = CurrencyUtil.div(alreadyMoney, alreadyPrice);
					fee = CurrencyUtil.div(money, p);
				} else {
					throw new ServiceException(ResultCode.CAN_NOT_BALANCE);
				}
			}
			map.put("fee", fee);
			map.put("money", money);
			return ResultUtil.data(map);
		}
		return null;
	}

}
